pub fn add(left: u64, right: u64) -> u64 {
    left + right
}

use std::{env, fs};
use std::error::Error;

pub fn run_config2(config: Config) {
    let file_content = fs::read_to_string(config.filepath)
        .unwrap_or(String::from(">>run2>> err to read file"));
    println!("- - - run_config2 get file - - -\n{}\n- - - end - - -", file_content);
}
//Box<dyn Error>
// dyn Error: 动态派发”，即运行时决定具体调用哪个类型的方法, 意味着 dyn Error 可以是任何实现了 Error trait 的类型, 而不需要在编译时知道具体的类型。
// Box：Box<T> 是 Rust 中的一个智能指针，用于在堆上动态分配对象。
pub fn run_config(config: Config) -> Result<(), Box<dyn Error>> {
    // ?: 错误传播运算符, 处理Result 或 Option 返回值时 可以直接向上传递
    let file_content = fs::read_to_string(config.filepath)?;
    println!("- - - run_config get file - - -\n{}\n- - - end - - -", file_content);
    let result = if config.rtype {
        println!(">>run_config>> RTYPE 字段不存在");
    } else {
        println!(">>run_config>> RTYPE 字段存在");
    };
    Ok(())
}


#[derive(Clone)]
pub struct Config {
    p1: String,
    pub filepath: String,
    rtype: bool
}


impl Config {
    pub fn new(arg: &[String]) -> Result<Config, &'static str> {
        if arg.len() < 3 {
            // &'static: 静态生命周期 在整个程序中可用 
            // 此处的字符串会被写到二进制程序中
            return Err("param less than 2");
        }
        let filepath = arg[1].clone();
        let p1 = arg[2].clone();
        let rtype = env::var("RTYPE").is_err();
        Ok(Config{p1, filepath, rtype: rtype})
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_works() {
        let result = add(2, 2);
        assert_eq!(result, 4);
    }
}